console.log('只剩下demo1');
// class 类型
/* 
1. class的写法
构造器当中怎么写（new实例对象时，new出来的实例对象中包含构造器constructor当中的属性或者方法）
原型对象上的方法
class类本自身上的方法怎么添加


2. 继承


3. ts当中写这些东西，时时刻刻要考虑一个问题，就是如何设计它的数据类型

4. ts当时class类定义数据类型时使用接口进行定义，如何定义

5. 接口在class类当中的用法
*/
// 但凡遇见变量都要给他设计数据类型
class Animal {
    // 声明一下构造器当中的属性的数据类型
    name: string;
    age: number;
    // 构造器
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
    // 在此处添加的属性，会直接加到 实例对象上
    sex: string = '男'
    // 此处该方法添加到了原型对象上 
    // 函数规定数据类型就两个方向：一类是形参的数据类型（形参指的是小括号当中的参数）   一类是函数返回值的数据（return后面的值，当函数没有return时，它是undefined）
    jump(str: string): void {
        console.log(str);
        console.log('跳了一下');
    }
    run(num: number): number {
        console.log('xxx');
        console.log(num);
        return num
    }
    // 在构造函数自身上添加属性和方法
    static song(): any {
        console.log('新冠结束了！！');
    }
    static color: string = '黄种人'

}
let cat = new Animal('喵喵', 1);
console.log(cat);
// 调用原型对象上的方法
cat.jump('111');
let dog = new Animal('dahuang', 11);
console.log(dog);
console.dir(Animal);
Animal.song();
console.log(Animal.color);

/* 
原型对象  该对象上的方法和属性如何添加上去 如何调用执行
实例对象   该对象上的方法和属性如何添加上去 如何调用执行
构造函数（class本身）该对象上的方法和属性如何添加上去 如何调用执行

*/

// 继承  父亲---》儿子  继承
// 父类 ---子类 继承

// Animal父类或者 基类 超类
// Person 子类 派生类  
// 继承通过extends  
// 通过super得到  super作为对象  super作为函数

class Person extends Animal {
    constructor(name: string, age: number) {
        // 作为函数存在执行
        super(name, age)
    }
    // 原型对象
    // 子类原型对象上只能去继承父类原型对象上的方法，不能去继承父类自身上的方法
    jump(str: string): void {
        super.jump(str);
        // super.song();
    }
    // class类自身
    static song(): any {
        super.song();
        // super.jump();
    }

}

let liming = new Person('liming', 111);
console.log(liming);

// 修饰符
// public 公开 哪里都能看能用 内部外部都能使用  默认就是公开的
// private  私有的  只能内部访问外部不能访问,子类当中也不能访问
// protected 受保护   内部能访问 子类当中能访问外部访问
// readonly 只读  只能在属性声明或者构造函数里进行初始化
class SunWei {
    public name: string;
    private age: number;
    protected sex: string;
    readonly hobby: string;
    constructor(name: string, age: number, sex: string, hobby: string) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.hobby = hobby
    }
    // 原型对象 操作这些属性名  在class内部进行操作
    show(): void {
        // 内部
        console.log(this.name);
        console.log(this.age);
        console.log(this.sex);
    }
}

let xiaosunwei = new SunWei('宝宝', 10, '男', '欢乐斗地主');
console.log(xiaosunwei);
// 外部
console.log(xiaosunwei.name);
// console.log(xiaosunwei.age);
// console.log(xiaosunwei.sex);
// 原型对象上的方法要调用 通过实例去调用
xiaosunwei.show();

class SunWenWen extends SunWei {
    constructor(name: string, age: number, sex: string, hobby: string) {
        super(name, age, sex, hobby);
    }
    // 原型对象上的方法
    test(): void {
        console.log(this.sex);
        // console.log(this.age);
    }
}
let Wen = new SunWenWen('宝贝儿', 5, '女', '振刀');
console.log(Wen);
Wen.test();
// console.log(Wen.sex);
console.log(xiaosunwei.hobby);
// 将原来的爱好变为了我的世界
// xiaosunwei.hobby = '我的世界';
console.log(xiaosunwei.hobby);



// 参数属性
class XiaoLi {
    // 对构造器中的属性进行类型规定
    /* name: string;
    age: number; */
    constructor(public name: string, public age: number) {
        this.name = name;
        this.age = age;
    }
}
let lili = new XiaoLi('zheshu', 10);
console.log(lili);

// 存取器
// get set
//志龙 吃饭睡觉打豆豆
class ZhiLong {
    name: string = '志龙';
    hobby: string = '吃饭睡觉打豆豆';
    /* constructor(name: string, hobby: string) {
        this.name = name;
        this.hobby = hobby;
    } */
    // get读取值
    get zlh(): string {
        return this.name + this.hobby;
    }
    // 当该值更改时就会触发set  触发set之后，获取新值，可以根据逻辑进行操作
    set zlh(value) {
        console.log(value);
    }

}
// let xiaozhilong = new ZhiLong('sizhe', '民风淳朴5');
let xiaozhilong = new ZhiLong();
console.log(xiaozhilong.zlh);
xiaozhilong.zlh = "肤白貌美大长腿";


// 抽象类
/* 
抽象类不能创建实例，它包含的都是一些抽象的方法，主要是为子类做父类用的
*/

abstract class Parent {
    abstract run();
    abstract jump();
}

class Son extends Parent {
    run() {
        console.log('子类当中的跑');
    }
    jump() {
        console.log('跳')
    }
}
let Danny = new Son();
Danny.run();
Danny.jump();


/*
哲书妈妈做饭呢   说哲书 买 酱油 盐

妈妈 父类   酱油 盐
儿子  子类   结果 酱油 盐拿回去



*/

// 多态
// 多态：父类型的引用指向了子类型的对象，不同类型的对象针对相同的方法，产生了不同的行为
// ？
// 接口
// 接口定义数据类型
/* 
对象 函数  类

*/


